#pragma once

#include "platform/platform.h"
#include <memory>
#include <functional>

typedef std::function <void(ez_socket_t sockfd, const struct sockaddr_in*) >NewConnectionCallback;


namespace EZTcp{

class EZLoop;
class EZSocketFD;


typedef std::function<ez_socket_t(EZLoop*, int, const NewConnectionCallback&)> accept_fn;


class EZListener
{
public:
	
	EZListener(EZLoop* loop, int port);
	
	~EZListener();

	// socket listen
	void listen();

	// nonblocking accept
	void accept();

	void stop();

	void set_new_connection_callback(NewConnectionCallback cb) {
		new_conn_fn_ = cb;
	}

	void set_accept_func(const accept_fn& cb){
		accept_fn_ = cb;
	}

    const std::string& listen_addr() const {
        return listen_addr_;
    }
    int listen_port() const {
        return port_;
    }
private:
	void _handle_accept();

private:
	ez_socket_t          fd_;// The listening socket fd
	EZLoop*                     loop_;
    std::string                 listen_addr_;
	int		                    port_;
	std::unique_ptr<EZSocketFD> chan_;
	NewConnectionCallback       new_conn_fn_;
	accept_fn				    accept_fn_;
};

}

